﻿//#define DEBUG_GUID

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;


namespace LightPersist
{

	/// <summary>
	/// Profiling helpers
	/// </summary>
	public static class LightProfiling
	{
		static readonly Stopwatch _last = new Stopwatch();

		/// <summary>
		/// Performance stopwatch logger
		/// </summary>
		/// <param name="description"></param>
		[Conditional("LightProfiling")]
		public static void Lap(string description)
		{
			_last.Stop();
			Trace.WriteLine("LightProfiling: " + description + "\t" + _last.ElapsedMilliseconds + "ms (" + _last.ElapsedTicks + " ticks)");
			_last.Reset();
			_last.Start();
		}

#if P

	static readonly Dictionary<string, TimeSpan> _mapSectionToTime = new Dictionary<string, TimeSpan>();

	public static PIndexer Check = new PIndexer();

	public sealed class PIndexer
	{
		public Action this [string sectionName]
		{
			set
			{
				var sw = Stopwatch.StartNew();
				value();
				sw.Stop();
				var newTime = sw.Elapsed;
				TimeSpan time;
				if(!_mapSectionToTime.TryGetValue(sectionName, out time))
				{
					_mapSectionToTime.Add(sectionName, newTime);
				}else
				{
					_mapSectionToTime[sectionName] = time + newTime;
				}
			}
		}
	}

	public static void Clear()
	{
		_mapSectionToTime.Clear();
	}

	public static string Result
	{
		get
		{
			return string.Join("\r\n", _mapSectionToTime.OrderByDescending(x => x.Value).Select(x =>
				string.Format("{0}\t{1} ({2}ms)",x.Key,x.Value.Ticks,x.Value.TotalMilliseconds.ToString("N01"))
			).ToArray());
		}
	}

#endif

	}


	static class DebugHelper
	{
		static readonly int _fullGuidLength = default(Guid).ToString().Length;

		public static string ToStringDebug(this object obj)
		{
			if (obj == null)
			{
				return "(null)";
			}
#if DEBUG
			if (obj is Guid)
			{
				var g = (Guid)obj;
				var shortID = g.ToString().Trim('-', '0').ToUpperInvariant();
				if (shortID.Length < 5)
				{
					shortID = "#" + shortID;
				}
				else if (shortID.Length == _fullGuidLength)
				{
					return "#" + g.ToString().Substring(_fullGuidLength - 3);
				}

				return shortID;
			}
			if (obj is string)
			{
				return (string)obj;
			}
			if (obj is IEnumerable)
			{
				return "[ " + string.Join(", ", ((IEnumerable)obj).Cast<object>().Select(x => x.ToStringDebug()).ToArray()) + "]";
			}
			return obj.ToString();
#else
			return obj.ToString();
#endif
		}

#if DEBUG && DEBUG_GUID
		static int _debugGuidCounter;
#endif

		public static Guid NewGuid()
		{
			// If you try to use existing database on debug you'll meet id conflicts
			// please, manage this condition on demand
#if DEBUG && DEBUG_GUID
			return new Guid(++_debugGuidCounter, 0, 0, new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 });
#else
			return Guid.NewGuid();
#endif
		}
	}
}